/*
 * Dcm_UDS0x22.c
 *
 *  Created on: 2018-1-16
 *      Author: Shute
 */
#include "UDS.h"

/****************************************************************
	     UDS:ReadDataByIdentifier (22 hex) service
 ***************************************************************/
#if(STD_ON == DCM_UDS_SERVICE0X22_ENABLED)

static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidNumbercheck(
        uint8 numberOfDid);

static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_CheckSupported(
        uint16 Did,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)ResOffset);

static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidCheck(
        Dcm_OpStatusType OpStatus,
		uint16 receiveDid,
		P2VAR(uint8, AUTOMATIC, DCM_VAR_NOINIT)pRangeDidCfgIndex,
		P2VAR(uint16, AUTOMATIC, DCM_VAR_NOINIT)pDidCfgIndex,
		P2VAR(boolean, AUTOMATIC, DCM_VAR_NOINIT)pRangeDidFlag);


static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidInfoCheck(
        uint8 DidInfoCfgIdx);


static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidSessionCheck(
        uint8  DidInfoCfgIndex,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)DidInfoSupportNum,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)DidSessionSupportNum);

static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidSecurityCheck(
        uint8  DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc);


static FUNC(boolean, DCM_CODE)Dsp_UDS0x22_DidEcuSignalCheck(
        uint16 DidCfgIndex,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)ResOffset);

static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidConditionCheck(
		Dcm_OpStatusType OpStatus,
		uint16  DidCfgIndex,
		P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc);


static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_ReadRangeDidDataLength(
        Dcm_OpStatusType OpStatus,
        uint16 RecDid,
        uint8 RangeDidCfgIndex,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)pDidSize,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc);


static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x22ServiceConditonCheck(
        uint8 ProtocolCtrlId);



static FUNC(Std_ReturnType, DCM_CODE)Dcm_UdsAssembleResponse(
        Dcm_OpStatusType OpStatus,
        uint8    ProtocolCtrlId,
        uint16   DidCfgIndex,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)ResOffset,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc);



static FUNC(Std_ReturnType, DCM_CODE)Dcm_UdsAssembleRangeDidResponse(
        Dcm_OpStatusType OpStatus,
        uint8    ProtocolCtrlId,
        uint16   RangeDidCfgIndex,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)ResOffset,
        uint16   RecDid,
        uint16   DidSize,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc);





#define DATA_LSB_MASK                   ((uint32)0x000000FFu)

/************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)Dcm_UdsAssembleResponse_0x2C(
        Dcm_OpStatusType OpStatus,
        uint8     MsgCtrlId,
        uint8  DDDidIndex,
        uint8    ProtocolCtrlId,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)ResOffset,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    uint8 DidSignalIndex;
    uint8 DidSignalNum;
    P2CONST(Dcm_DspDataType,TYPEDEF,DCM_CONST) pDspDidData;
    Std_ReturnType ret = E_OK;
    P2VAR(Dcm_DDDidElementsDataTypes,TYPEDEF,DCM_CONST) DDDid;
    uint8 DDDidNum;
    uint8 iloop;
    uint8 IdInfoIndex;
    uint8 RangeInfoIndex;
    P2CONST(Dcm_DspReadMemoryRangeInfoType, AUTOMATIC, DCM_VAR_NOINIT)
     pDcmDspReadMemoryRangeInfo;
    P2CONST(Dcm_DspMemoryIdInfoType, AUTOMATIC, DCM_VAR_NOINIT)
     pDcmDspMemoryIdInfo;
    uint8 MemoryIdentifier = 0;
    uint16 Did;
    uint8  Pos;
    uint8  Data[DCM_CHANNEL_LENGTH] = {0};
    uint8     Index;
    boolean   Flag = FALSE;
    uint16 pDidCfgIndex = 0;
    uint16 DidSignalPos = 0;
    uint16 Size;

    DDDidNum = Dcm_DDDid[DDDidIndex].DDDIDNumOfElements;
    DDDid = Dcm_DDDid[DDDidIndex].DcmDspAlternativeArgumentData;
    for (iloop = 0; iloop < DDDidNum; iloop++)
    {
        if (DDDid->Subfunction == DCM_UDS0X2C_01_DDBYDID)
        {
            Did = (uint16)(DDDid->Data & 0xFFFFUL);
            Pos = (uint8)((DDDid->Data & 0xFF0000UL) >> 16u);
            for (Index = 0;(Index < Dcm_DspCfg.DcmDspDidNum)
            && (FALSE == Flag); Index++)
            {
                /*single did check*/
                if ((Did == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId)
                &&(TRUE == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidUsed))
                {
                    Flag = TRUE;
                    pDidCfgIndex = Index;
                }
            }

            DidSignalNum = Dcm_DspCfg.pDcmDspDid[pDidCfgIndex].DcmDspDidSignalNum;
            for (DidSignalIndex = 0; DidSignalIndex < DidSignalNum; DidSignalIndex ++)
            {
                pDspDidData = Dcm_DspCfg.pDcmDspDid[pDidCfgIndex].
                        pDcmDspDidSignal[DidSignalIndex].pDcmDspDidData;
                Size = 0;
                if (DCM_UINT8_DYN == pDspDidData->DcmDspDataType)
                {
                    /*DidDataSize is dynamic*/
                    if (NULL_PTR == pDspDidData->DcmDspDataReadDataLengthFnc)
                    {
                        /*DcmDspDidReadDataLengthFnc is NULL,send NRC 0x22*/
                        (*pNrc) = DCM_E_CONDITIONSNOTCORRECT;
                        ret = E_NOT_OK;
                    }
                    else if((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                        || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
                    {
                        ret = pDspDidData->DcmDspDataReadDataLengthFnc(DCM_INVALID_UINT8, &Size);
                    }
                    else if((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                         || (USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
                         || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort)
                         || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
                    {
                        ret = pDspDidData->DcmDspDataReadDataLengthFnc(OpStatus, &Size);
                    }
                    else
                    {}
                }
                else
                {
                    /*DidDataSize is fixed*/
                    Size = ((pDspDidData->DcmDspDataSize + 7u) >> 3u);
                }

                DidSignalPos += ((Dcm_DspCfg.pDcmDspDid[pDidCfgIndex].
                        pDcmDspDidSignal[DidSignalIndex].DcmDspDidDataPos + 7u) >> 3u);
                if (NULL_PTR == pDspDidData->DcmDspDataReadFnc)
                {
                    /*DcmDspDataReadFnc is NULL,send NRC 0x22*/
                    (void)DsdInternal_SetNrc(ProtocolCtrlId, DCM_E_CONDITIONSNOTCORRECT);
                    DsdInternal_ProcessingDone(ProtocolCtrlId);
                    return E_NOT_OK;
                }
                else if ((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                        || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
                {
                    ret = pDspDidData->DcmDspDataReadFnc(
                            DCM_INVALID_UINT8,
                            &Data[DidSignalPos],
                            NULL_PTR);
                }
                else if ((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
                {
                    ret = pDspDidData->DcmDspDataReadFnc(
                            OpStatus,
                            &Data[DidSignalPos],
                            NULL_PTR);
                }
                else if ((USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
                        || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
                {
                    ret = pDspDidData->DcmDspDataReadFnc(
                            OpStatus,
                            &Data[DidSignalPos],
                            pNrc);
                }
                else
                {}

                if(E_NOT_OK == ret)
                {
                    (void)DsdInternal_SetNrc(ProtocolCtrlId, *pNrc); /*NRC=0x22*/
                    DsdInternal_ProcessingDone(ProtocolCtrlId);
                    return E_NOT_OK;
                }
                DidSignalPos += Size;
            }
            Dcm_MemoryCopy(
                    &(Data[Pos]),
                    &(Dcm_Channel[*ResOffset]),
                    DDDid->Size);
            *ResOffset += DDDid->Size;
        }
        else if (DDDid->Subfunction == DCM_UDS0X2C_02_DDBYMEMORY)
        {
            for(IdInfoIndex = 0u;
                IdInfoIndex < Dcm_DspCfg.pDcmDspMemory->DcmDspMemoryIdInfoNum;
                IdInfoIndex++)
            {
                pDcmDspMemoryIdInfo =
                   &(Dcm_DspCfg.pDcmDspMemory->DcmDspMemoryIdInfo[IdInfoIndex]);
                if (pDcmDspMemoryIdInfo != NULL_PTR)
                {
                    for(RangeInfoIndex = 0;
                        RangeInfoIndex < pDcmDspMemoryIdInfo->DcmDspReadMemoryRangeInfoNum;
                        RangeInfoIndex++)
                    {
                        pDcmDspReadMemoryRangeInfo =
                           &(pDcmDspMemoryIdInfo->DcmDspReadMemoryRangeInfo[RangeInfoIndex]);
                        if (pDcmDspReadMemoryRangeInfo != NULL_PTR)
                        {
                            if ((pDcmDspReadMemoryRangeInfo->DcmDspReadMemoryRangeLow
                                    <= DDDid->Data)
                                && (pDcmDspReadMemoryRangeInfo->DcmDspReadMemoryRangeHigh
                                        >= (DDDid->Data + DDDid->Size - 1u)))
                            {
                                MemoryIdentifier =
                                  Dcm_DspCfg.pDcmDspMemory->DcmDspMemoryIdInfo[IdInfoIndex].
                                  DcmDspMemoryIdValue;
                            }
                        }
                    }
                }
            }

            ret = Dcm_ReadMemory(OpStatus,
                                    MemoryIdentifier,
                                    DDDid->Data,
                                    DDDid->Size,
                                    &Dcm_Channel[*ResOffset],
                                    pNrc);
            if (DCM_READ_FAILED == ret)
            {
                /*the processing is not successful,send NRC */
                (void)DsdInternal_SetNrc(ProtocolCtrlId, *pNrc);
                DsdInternal_ProcessingDone(ProtocolCtrlId);
                return E_NOT_OK;
            }
#if(STD_ON == DCM_DSLDIAGRESP_FORCERESPENDEN)
            else if(DCM_READ_FORCE_RCRRP == ret)
            {
                /*the processing is pending,send NRC 0x78[SWS_Dcm_00839][SWS_Dcm_00840] */
                (void)DsdInternal_SetNrc(ProtocolCtrlId, DCM_E_RESPONSE_PENDING);
                DsdInternal_ProcessingDone(ProtocolCtrlId);
                Dcm_MsgCtrl[MsgCtrlId].Dcm_Ret = DCM_E_FORCE_RCRRP;
                return DCM_E_PENDING;
            }
#endif
            else if (DCM_READ_PENDING == ret)
            {
                Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
                return ret;
            }
            else
            {
                /*idle*/
            }
            *ResOffset += DDDid->Size;
        }
        else
        {
            *pNrc = DCM_E_CONDITIONSNOTCORRECT;
            ret = E_NOT_OK;
        }
        DDDid++;
    }
    return ret;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif
#endif
/************************/
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidNumbercheck(
        uint8 numberOfDid)
{
	Std_ReturnType ret = E_OK;

	if (0u != (Dcm_DspCfg.DcmDspMaxDidToRead))
	{
		/*check the limitation of number of required DID*/
		if (numberOfDid > (Dcm_DspCfg.DcmDspMaxDidToRead))
		{
			ret = E_NOT_OK;
		}
	}

	return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_CheckSupported(
        uint16 Did,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)ResOffset)
{
    uint32 SupportBuffer = 0;
    uint8 iloop = 0;
    while (iloop < Dcm_DspCfg.DcmDspDidNum)
    {
        if((Dcm_DspCfg.pDcmDspDid[iloop].DcmDspDidId >= (Did +0x01u))
           && (Dcm_DspCfg.pDcmDspDid[iloop].DcmDspDidId <= (Did +0x20u)))
        {
            SupportBuffer |=
             (uint32)1UL << (0x20u - (Dcm_DspCfg.pDcmDspDid[iloop].DcmDspDidId - Did));
        }
        iloop++;
    }

    if (SupportBuffer != 0UL)
    {
        SchM_Enter_Dcm(Dcm_Channel);
        Dcm_Channel[*ResOffset] = (uint8)((Did) >> 8u); /*echo of DID MSB*/
        *ResOffset += 1u;
        Dcm_Channel[*ResOffset] = (uint8)(Did);
        *ResOffset += 1u;
        /*take every byte of uint32 SupportBuffer,and fill in Dcm_Channel*/
        Dcm_Channel[*ResOffset] = (uint8)((SupportBuffer & (DATA_LSB_MASK << 24u)) >> 24u);
        *ResOffset += 1u;
        Dcm_Channel[*ResOffset] = (uint8)((SupportBuffer & (DATA_LSB_MASK << 16u)) >> 16u);
        *ResOffset += 1u;
        Dcm_Channel[*ResOffset] = (uint8)((SupportBuffer & (DATA_LSB_MASK << 8u)) >> 8u);
        *ResOffset += 1u;
        Dcm_Channel[*ResOffset] = (uint8)(SupportBuffer & DATA_LSB_MASK);
        SchM_Exit_Dcm(Dcm_Channel);
        *ResOffset += 1u;
#if(STD_ON == DCM_PAGEDBUFFER_ENABLED)
        Dcm_PageBufferData.LastFilledSize = 6u;
#endif
    }
    else
    {
        return E_NOT_OK;
    }

    return E_OK;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

/************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidCheck(
        Dcm_OpStatusType OpStatus,
		uint16 receiveDid,
		P2VAR(uint8, AUTOMATIC, DCM_VAR_NOINIT)pRangeDidCfgIndex,
		P2VAR(uint16, AUTOMATIC, DCM_VAR_NOINIT)pDidCfgIndex,
		P2VAR(boolean, AUTOMATIC, DCM_VAR_NOINIT)pRangeDidFlag)
{
    Dcm_DidSupportedType    DidSupported;
    uint16     Index;
    uint8     Idx;
	boolean   Flag = FALSE;
	boolean   Flagx = FALSE;
    Std_ReturnType  ret = E_NOT_OK;
#if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
    uint8 iloop;
#endif

    *pRangeDidFlag = FALSE;
    /*SWS_Dcm_00438*/
    /*first check whether the receiveDid is single did*/
	for (Index = 0;(Index < Dcm_DspCfg.DcmDspDidNum) && (FALSE == Flag); Index++)
	{
	    /*single did check*/
        if ((receiveDid == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId)
        &&(TRUE == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidUsed))
        {
#if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
            if ((receiveDid > 0xF200u) && (receiveDid < 0xF3FFu)
               && (Dcm_DspCfg.pDcmDspDidInfo[Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidInfoIndex].
                       DcmDspDidDynamicallyDefined == TRUE)
               && (Dcm_DspCfg.pDcmDspDidInfo[Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidInfoIndex].
                       DcmDspDDDIDMaxElements > 0u))
            {
               for (iloop = 0; (iloop < DCM_DSP_DDDID_MAX_NUMBER) && (Flag == FALSE); iloop++)
               {
                   if (Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId == Dcm_DDDid[iloop].DDDid)
                   {
                       Flag = TRUE;
                       (*pDidCfgIndex) = Index;
                       ret = E_OK;
                   }
               }
            }
            else
#endif
            {
                Flag = TRUE;
                (*pDidCfgIndex) = Index;
                ret = E_OK;
            }
        }
    }
	/*if the receiveDid is not single did,the check whether the receiveDid is range did*/
    if (FALSE == Flag)
    {
        /*range did check*/
        if ((receiveDid < 0xF200u) || (receiveDid > 0xF3FFu))
        {
            /*range did can not be DDDid*/
            for (Idx = 0;
                    (Idx < Dcm_DspCfg.DcmDspDidRangeNum) && (FALSE == Flagx);
                    Idx++)
            {
                /*this range not have gaps*/
                if ((receiveDid >= Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIdentifierLowerLimit)
                    && (receiveDid <= Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIdentifierUpperLimit))
                {
                    if (TRUE == Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeHasGaps)
                    {
                        if (FALSE == Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeUsePort)
                        {
                            if (Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIsDidAvailableFnc
                                    != NULL_PTR)
                            {
                                ret = Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIsDidAvailableFnc(
                                        receiveDid,
                                        OpStatus,
                                        &DidSupported);
                                if (ret == E_OK)
                                {
                                    if (DCM_DID_SUPPORTED == DidSupported)
                                    {
                                        *pRangeDidCfgIndex = Idx;
                                        *pRangeDidFlag = TRUE;
                                        Flagx = TRUE;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        *pRangeDidCfgIndex = Idx;
                        *pRangeDidFlag = TRUE;
                        Flagx = TRUE;
                    }
                }
            }
        }

        if (FALSE == Flagx)
        {
            ret = E_NOT_OK;
        }
        else
        {
            (*pDidCfgIndex) = Index;
            ret = E_OK;
        }
    }

    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidInfoCheck(
        uint8 DidInfoCfgIdx)
{
    Std_ReturnType  ret = E_NOT_OK;

	if (Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIdx].pDcmDspDidRead != NULL_PTR)
	{
		ret = E_OK;
	}

	return ret;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidSessionCheck(
        uint8  DidInfoCfgIndex,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)DidInfoSupportNum,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)DidSessionSupportNum)
{
    uint8   Index;
	boolean Flag = FALSE;
	P2CONST(Dcm_DspDidReadType, AUTOMATIC, DCM_APPL_CONST) pDspDidRead;
	Std_ReturnType   ret = E_OK;

	/***************************************
	 * pDcmDspDidRead is NULL_PTR
	 ***************************************/
	pDspDidRead  = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidRead;
	if (NULL_PTR == pDspDidRead)
	{
		/*Dcm433:if the DcmDspDidRead of
		 * required Did is not configured,send NRC 0x31*/
        ret = E_NOT_OK;
	}
	else
	{
	    (*DidInfoSupportNum)++;
	    if (pDspDidRead->DcmDspDidReadSessionRefNum != 0u)
	    {
            for (Index = 0;
                    (Index < (pDspDidRead->DcmDspDidReadSessionRefNum))
                            && (FALSE == Flag);
                    Index++)
            {
                if (Dcm_MkCtrl.Dcm_ActiveSes
                        == pDspDidRead->pDcmDspDidReadSessionRow[Index])
                {
                    Flag = TRUE;
                    (*DidSessionSupportNum)++;
                }
            }
            if (FALSE == Flag)
            {
                ret = E_NOT_OK;
            }
	    }
	    else
	    {
            ret = E_OK;
            (*DidSessionSupportNum)++;
        }
	}
    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/************************/
#if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DDDidSessionCheck(
        uint8  DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    uint8   Index;
    boolean Flag = FALSE;
    P2CONST(Dcm_DspDidReadType, AUTOMATIC, DCM_APPL_CONST) pDspDidRead;
    Std_ReturnType   ret = E_OK;

    /***************************************
     * pDcmDspDidRead is NULL_PTR
     ***************************************/
    pDspDidRead  = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidRead;
    if (NULL_PTR == pDspDidRead)
    {
        /*Dcm433:if the DcmDspDidRead of
         * required Did is not configured,send NRC 0x31*/
        (*pNrc) = DCM_E_REQUESTOUTOFRANGE;
        ret = E_NOT_OK;
    }
    else
    {
        if (pDspDidRead->DcmDspDidReadSessionRefNum != 0u)
        {
            for (Index = 0;
                    (Index < (pDspDidRead->DcmDspDidReadSessionRefNum))
                            && (FALSE == Flag);
                    Index++)
            {
                if (Dcm_MkCtrl.Dcm_ActiveSes
                        == pDspDidRead->pDcmDspDidReadSessionRow[Index])
                {
                    Flag = TRUE;
                }
            }
            if (FALSE == Flag)
            {
                /*Dcm435:the reading processing is not supported
                 * in current security level,send NRC 0x7F*/
               (*pNrc) = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;
                ret = E_NOT_OK;
            }
        }
        else
        {
            ret = E_OK;
        }
    }
    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif
#endif

/***************************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidSecurityCheck(
        uint8  DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    P2CONST(Dcm_DspDidReadType, AUTOMATIC, DCM_APPL_CONST) pDspDidRead;
    uint8    SecNum;
    uint8    Index;
    Std_ReturnType   ret = E_OK;
    boolean  Flag = FALSE;



	/***************************************
	 * pDcmDspDidRead is NULL_PTR
	 ***************************************/
	pDspDidRead  = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidRead;
	if (NULL_PTR == pDspDidRead)
	{
		/*Dcm433:if the DcmDspDidRead of required Did is not configured,send NRC 0x31*/
        (*pNrc) = DCM_E_REQUESTOUTOFRANGE;
        ret = E_NOT_OK;
	}
	else
	{
	    SecNum = pDspDidRead->DcmDspDidReadSecurityLevelRefNum;
	    if (SecNum != 0u)
	    {
            for (Index = 0; (Index < SecNum) && (FALSE == Flag); Index++)
            {
                if (Dcm_MkCtrl.Dcm_ActiveSec
                        == pDspDidRead->pDcmDspDidReadSecurityLevelRow[Index])
                {
                    Flag = TRUE;
                }
            }
            if (FALSE == Flag)
            {
                /*Dcm435:the reading processing is not supported
                 *  in current security level,send NRC 0x33*/
               (*pNrc) = DCM_E_SECURITYACCESSDENIED;
                ret = E_NOT_OK;
            }
	    }
	    else
	    {
	        ret = E_OK;
	    }
	}
	return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif
#if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DDDIDcheckPerSourceDID(
        uint16 DDDidIdx,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    Std_ReturnType  ret = E_OK;
    P2VAR(Dcm_DDDidElementsDataTypes,TYPEDEF,DCM_CONST) DDDid;
    uint8 DDDidNum;
    uint8 iloop;
    uint16 Did;
    uint8     RangeDidCfgIndex = 0;
    uint16     DidCfgIndex;
    boolean   RangeDidFlag;
    uint8     DidInfoCfgIndex;
    uint8 IdInfoIndex;
    P2CONST(Dcm_DspReadMemoryRangeInfoType, AUTOMATIC, DCM_VAR_NOINIT)
     pDcmDspReadMemoryRangeInfo;
    P2CONST(Dcm_DspMemoryIdInfoType, AUTOMATIC, DCM_VAR_NOINIT)
     pDcmDspMemoryIdInfo;
    uint8 RangeInfoIndex;
    uint8 index;
    uint8 SecNum;

    /*SWS_Dcm_00864, SWS_Dcm_00865*/
    if (Dcm_DspCfg.DcmDspDDDIDcheckPerSourceDID != NULL_PTR)
    {
        if (TRUE == (*(Dcm_DspCfg.DcmDspDDDIDcheckPerSourceDID)))
        {
            DDDidNum = Dcm_DDDid[DDDidIdx].DDDIDNumOfElements;
            DDDid = Dcm_DDDid[DDDidIdx].DcmDspAlternativeArgumentData;
            for (iloop = 0; (iloop < DDDidNum) && (E_NOT_OK != ret); iloop++)
            {
                if (DDDid->Subfunction == DCM_UDS0X2C_01_DDBYDID)
                {
                    Did = (uint16)(DDDid->Data & 0xFFFFu);
                    ret = DspInternalUDS0x22_DidCheck(DCM_INITIAL,
                                                Did,
                                                &RangeDidCfgIndex,
                                                &DidCfgIndex,
                                                &RangeDidFlag);
                    if (ret == E_OK)
                    {
                        if (TRUE == RangeDidFlag)
                        {
                            DidInfoCfgIndex =
                              Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].DcmDspDidRangeInfoIndex;
                        }
                        else
                        {
                            DidInfoCfgIndex = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].DcmDspDidInfoIndex;
                        }

                        /*SWS_Dcm_00433,SWS_Dcm_00434,SWS_Dcm_00435*/
                        /*check the current session*/
                        #if(STD_ON == DCM_SESSION_FUNC_ENABLED)
                        ret = DspInternalUDS0x22_DDDidSessionCheck(DidInfoCfgIndex,pNrc);
                        if(E_NOT_OK == ret)
                        {
                            return  E_NOT_OK;
                        }
                        #endif

                        /***************************************/
                        /*check the current security level*/
                        #if(STD_ON == DCM_SECURITY_FUNC_ENABLED)
                        ret = DspInternalUDS0x22_DidSecurityCheck(DidInfoCfgIndex,pNrc);
                        if(E_NOT_OK == ret)
                        {
                            return  E_NOT_OK;
                        }
                        #endif
                    }
                }
                else if (DDDid->Subfunction == DCM_UDS0X2C_02_DDBYMEMORY)
                {
                   ret = E_NOT_OK;
                   for(IdInfoIndex = 0u;
                       IdInfoIndex < Dcm_DspCfg.pDcmDspMemory->DcmDspMemoryIdInfoNum;
                       IdInfoIndex++)
                   {
                       pDcmDspMemoryIdInfo =
                        &(Dcm_DspCfg.pDcmDspMemory->DcmDspMemoryIdInfo[IdInfoIndex]);
                       if (pDcmDspMemoryIdInfo != NULL_PTR)
                       {
                           for(RangeInfoIndex = 0;
                               RangeInfoIndex < pDcmDspMemoryIdInfo->DcmDspReadMemoryRangeInfoNum;
                               RangeInfoIndex++)
                           {
                               pDcmDspReadMemoryRangeInfo =
                                &(pDcmDspMemoryIdInfo->DcmDspReadMemoryRangeInfo[RangeInfoIndex]);
                               SecNum = pDcmDspReadMemoryRangeInfo->DcmDspReadMemorySecurityLevelRefNum;
                               if (SecNum != 0u)
                               {
                                   for (index = 0; (index < SecNum); index++)
                                   {
                                       if (Dcm_MkCtrl.Dcm_ActiveSec
                                        == pDcmDspReadMemoryRangeInfo->pDcmDspReadMemorySecurityLevelRow[index])
                                       {
                                           ret = E_OK;
                                       }
                                   }
                               }
                               else
                               {
                                    ret = E_OK;
                               }
                           }
                       }
                   }
                   if (ret == E_NOT_OK)
                   {
                       (*pNrc) = DCM_E_REQUESTOUTOFRANGE;
                   }
                }
                else
                {
                    /*idle*/
                }
            }
        }
    }
    return ret;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif
#endif

/************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(boolean, DCM_CODE)Dsp_UDS0x22_DidEcuSignalCheck(
        uint16 DidCfgIndex,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)ResOffset)
{
	uint8 DidSignalIndex;
	uint8 DidSignalNum;
	P2CONST(Dcm_DspDataType,TYPEDEF,DCM_CONST) pDspDidData;
	boolean readDidSignalFlag = FALSE;

	DidSignalNum = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].DcmDspDidSignalNum;
	for (DidSignalIndex = 0; DidSignalIndex < DidSignalNum; DidSignalIndex ++)
	{
		pDspDidData = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
		        pDcmDspDidSignal[DidSignalIndex].pDcmDspDidData;
		if (USE_ECU_SIGNAL == pDspDidData->DcmDspDataUsePort)
		{
			pDspDidData->DcmDspDataReadEcuSignalFnc(&Dcm_Channel[*ResOffset]);
			*ResOffset += ((pDspDidData->DcmDspDataSize + 7u) >> 3u);
			readDidSignalFlag = TRUE;
		}
		else if (USE_BLOCK_ID == pDspDidData->DcmDspDataUsePort)
		{
#if(NVM_ENABLE == STD_ON)
			/*SWS_Dcm_00560*/
			(void)NvM_ReadBlock(pDspDidData->DcmDspDataBlockId, &Dcm_Channel[*ResOffset]);
			*ResOffset += ((pDspDidData->DcmDspDataSize + 7u) >> 3u);
#endif
		}
		else
		{

		}
	}

	return readDidSignalFlag;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_DidConditionCheck(
		Dcm_OpStatusType OpStatus,
		uint16  DidCfgIndex,
		P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
	uint8 DidSignalIndex;
	uint8 DidSignalNum;
	P2CONST(Dcm_DspDataType,TYPEDEF,DCM_CONST) pDspDidData;
	Std_ReturnType ret = E_OK;

	DidSignalNum = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].DcmDspDidSignalNum;
	for (DidSignalIndex = 0; DidSignalIndex < DidSignalNum; DidSignalIndex ++)
	{
		pDspDidData = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
		        pDcmDspDidSignal[DidSignalIndex].pDcmDspDidData;
		if ((TRUE == pDspDidData->DcmConditionCheckReadFncUsed)
		    && (NULL_PTR != pDspDidData->DcmDspDataConditionCheckReadFnc))
	    {
			if ((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
			{
				ret = pDspDidData->DcmDspDataConditionCheckReadFnc(DCM_INVALID_UINT8, pNrc);
			}
			else if ((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
			{
				ret = pDspDidData->DcmDspDataConditionCheckReadFnc(OpStatus, pNrc);
			}
			else
			{}
	    }
        if ((TRUE == pDspDidData->DcmConditionCheckReadFncUsed)
            && (NULL_PTR == pDspDidData->DcmDspDataConditionCheckReadFnc))
        {
            *pNrc = DCM_E_CONDITIONSNOTCORRECT;
            ret = E_NOT_OK;
        }
	}

	return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/***************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x22_ReadRangeDidDataLength(
        Dcm_OpStatusType OpStatus,
        uint16 RecDid,
        uint8 RangeDidCfgIndex,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)pDidSize,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    Std_ReturnType ret;

    if (NULL_PTR == Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].
            DcmDspDidRangeReadDataLengthFnc)
    {
        /*DcmDspDidReadDataLengthFnc is NULL,send NRC 0x22*/
        (*pNrc) = DCM_E_CONDITIONSNOTCORRECT;
        return E_NOT_OK;
    }

    ret = Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].DcmDspDidRangeReadDataLengthFnc(
            RecDid,
            OpStatus,
            pDidSize);

    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/************************/
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x22ServiceConditonCheck(
        uint8 ProtocolCtrlId)
{
	Std_ReturnType ret;
	uint8     MsgCtrlId;

    /*************************************************/
    #if(STD_ON == DCM_SESSION_FUNC_ENABLED)
    /*session check,check whether the current
     * session supports the request service*/
    ret = DsdInternal_SesCheck(ProtocolCtrlId,
            SID_READ_DATA_BY_IDENTIFIER);
    if(E_NOT_OK == ret)
    {
        /****@req DCM-FUNR-073[DCM211]****/
        /*the current session does not support
         *  the request service,send NRC = 0x7F*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,
                DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
    #endif

    /*************************************************/
    #if(STD_ON == DCM_SECURITY_FUNC_ENABLED)
    /*security check,check whether the current security supports the request service*/
    ret = DsdInternal_SecurityCheck(ProtocolCtrlId,
            SID_READ_DATA_BY_IDENTIFIER);
    if(E_NOT_OK == ret)
    {
        /****@req DCM-FUNR-074[DCM217]****/
        /*the current security does not support
         *  the request service,send NRC = 0x33*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,
                DCM_E_SECURITYACCESSDENIED);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
    #endif

	/*************************************************/
	/*if the required protocol is configured,get the index of runtime datum*/
	MsgCtrlId  = Dcm_ProtocolCtrl[ProtocolCtrlId].MsgCtrlIndex;

	/*check the message length*/
	if ((0u == (Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen & 1u))\
		||(Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen
		        < DCM_UDS0X22_REQ_DATA_MINLENGTH))
	{
		/*the length of message is not correct,send NRC 0x13*/
		(void)DsdInternal_SetNrc(ProtocolCtrlId,
		        DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
		DsdInternal_ProcessingDone(ProtocolCtrlId);
		return E_NOT_OK;
	}


	return E_OK;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

/************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)Dcm_UdsAssembleResponse(
        Dcm_OpStatusType OpStatus,
        uint8    ProtocolCtrlId,
        uint16   DidCfgIndex,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)ResOffset,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
	uint16 DidSignalPos;
	uint8 DidSignalIndex;
	uint8 DidSignalNum;
	P2CONST(Dcm_DspDataType,TYPEDEF,DCM_CONST) pDspDidData;
	Std_ReturnType ret = E_OK;
	uint16 Size;

	DidSignalNum = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].DcmDspDidSignalNum;
	for (DidSignalIndex = 0; DidSignalIndex < DidSignalNum; DidSignalIndex ++)
	{
		pDspDidData = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
		        pDcmDspDidSignal[DidSignalIndex].pDcmDspDidData;
        Size = 0;
        if (DCM_UINT8_DYN == pDspDidData->DcmDspDataType)
        {
            /*DidDataSize is dynamic*/
            if (NULL_PTR == pDspDidData->DcmDspDataReadDataLengthFnc)
            {
                /*DcmDspDidReadDataLengthFnc is NULL,send NRC 0x22*/
                (*pNrc) = DCM_E_CONDITIONSNOTCORRECT;
                ret = E_NOT_OK;
            }
            else if((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
            {
                ret = pDspDidData->DcmDspDataReadDataLengthFnc(
                        DCM_INVALID_UINT8,
                        &Size);
            }
            else if((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
            {
                ret = pDspDidData->DcmDspDataReadDataLengthFnc(
                        OpStatus,
                        &Size);
            }
            else
            {}
        }
        else
        {
            /*DidDataSize is fixed*/
            Size = ((pDspDidData->DcmDspDataSize + 7u) >> 3u);
        }
		DidSignalPos = *ResOffset +
		        ((Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
		                pDcmDspDidSignal[DidSignalIndex].DcmDspDidDataPos + 7u)
		                >> 3u);
		if (NULL_PTR == pDspDidData->DcmDspDataReadFnc)
		{
			/*DcmDspDataReadFnc is NULL,send NRC 0x22*/
			(void)DsdInternal_SetNrc(ProtocolCtrlId,
			        DCM_E_CONDITIONSNOTCORRECT);
			DsdInternal_ProcessingDone(ProtocolCtrlId);
			return E_NOT_OK;
		}
		else if ((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
		{
			ret = pDspDidData->DcmDspDataReadFnc(
			        DCM_INVALID_UINT8,
			        &Dcm_Channel[DidSignalPos],
			        NULL_PTR);
		}
		else if ((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
		{
			ret = pDspDidData->DcmDspDataReadFnc(
			        OpStatus,
			        &Dcm_Channel[DidSignalPos],
			        NULL_PTR);
		}
		else if ((USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
                || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
		{
			ret = pDspDidData->DcmDspDataReadFnc(
			        OpStatus,
			        &Dcm_Channel[DidSignalPos],
			        pNrc);
		}
		else
		{
		}

		if(E_NOT_OK == ret)
		{
			(void)DsdInternal_SetNrc(ProtocolCtrlId, *pNrc); /*NRC=0x22*/
			DsdInternal_ProcessingDone(ProtocolCtrlId);
		}
	    /*ResOffset equal to last position
	     *  add last size of the signal of did*/
	    *ResOffset = DidSignalPos + Size;
	}

	return ret;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif


/************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)Dcm_UdsAssembleRangeDidResponse(
        Dcm_OpStatusType OpStatus,
        uint8    ProtocolCtrlId,
        uint16   RangeDidCfgIndex,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)ResOffset,
        uint16   RecDid,
        uint16   DidSize,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    Std_ReturnType ret;

    if (NULL_PTR
        == Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].DcmDspDidRangeReadDidFnc)
    {
        (void)DsdInternal_SetNrc(ProtocolCtrlId, DCM_E_CONDITIONSNOTCORRECT);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }

    ret = Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].DcmDspDidRangeReadDidFnc(
            RecDid,
            &Dcm_Channel[*ResOffset],
            OpStatus,
            DidSize,
            pNrc);

    if(E_NOT_OK == ret)
    {
        (void)DsdInternal_SetNrc(ProtocolCtrlId, *pNrc); /*NRC=0x22*/
        DsdInternal_ProcessingDone(ProtocolCtrlId);
    }

    *ResOffset = *ResOffset + DidSize;

    return ret;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/************************/
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
Std_ReturnType Dcm_UDS0x22(
		Dcm_OpStatusType OpStatus,
		uint8  ProtocolCtrlId,
		P2VAR(Dcm_NegativeResponseCodeType,AUTOMATIC,DCM_VAR) ErrorCode)
{

#if (STD_ON == DCM_DSP_DID_FUNC_ENABLED)
	uint16    DidCfgIndex;
	uint16    RecDid;
	uint16    DidSize = 0;
	uint16    ResOffset;
	uint16    Offset;
	uint8     RangeDidCfgIndex;
    uint8     DidInfoCfgIndex;
    uint16     ReqOffset;
    uint8     TxChannelCtrlIndex;
    uint8     TxChannelCfgIndex;
    uint8     DidNum;
    uint16     Index0;
	boolean   ReadDidSignalFlag;
	boolean   RangeDidFlag;
    uint8 DidSessionSupportNum = 0;
    uint8 DidInfoSupportNum = 0;
    uint8 NoFindDidNum = 0;
    uint8 NoFindDidReadNum = 0;
    boolean CheckOK;
    boolean   DidSessionCheck = TRUE;
#if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
	uint8     iloop;
    boolean   Find;
#endif
#endif
    uint8     MsgCtrlId;
    uint8 MixPid = 0;
    uint8 noFindPidNum = 0;
	Std_ReturnType ret;

#if (STD_OFF == DCM_DSP_DID_FUNC_ENABLED)
	/*NRC 0x31:request out of range*/
	(void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
	DsdInternal_ProcessingDone(ProtocolCtrlId);
	return E_NOT_OK;
#else

	MsgCtrlId  = Dcm_ProtocolCtrl[ProtocolCtrlId].MsgCtrlIndex;
    /**************************************************/
	/*calculate the number of required DID*/
	DidNum = (uint8)(Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen >> 1u);
	ret = DspInternalUDS0x22_DidNumbercheck(DidNum);
    if(E_NOT_OK == ret)
    {
        /*NRC = 0x13*/
		(void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
		DsdInternal_ProcessingDone(ProtocolCtrlId);
		return E_NOT_OK;
    }

    /************************************************/
	/*get the runtime datum index*/
	TxChannelCtrlIndex = Dcm_MsgCtrl[MsgCtrlId].Dcm_TxCtrlChannelIndex;
	TxChannelCfgIndex = Dcm_ChannelCtrl[TxChannelCtrlIndex].Dcm_ChannelCfgIndex;
	Offset = (Dcm_DslCfg.pDcmChannelCfg)[TxChannelCfgIndex].offset;
#if (TRUE == DCM_PAGEDBUFFER_ENABLED)
	if (0u == Dcm_PageBufferData.PageIndex)
	{
		Dcm_PageBufferData.PageTxOK = FALSE;
#endif
		Dcm_Channel[Offset] = 0x62; /*response SID*/
		ResOffset  = (uint16)(Offset + 1u);
		ReqOffset  = 1;
		Index0 = 0u;
#if (TRUE == DCM_PAGEDBUFFER_ENABLED)
		Dcm_PageBufferData.LastFilled = TRUE;
	}
	else
	{
		if (Dcm_PageBufferData.PageTxOK != TRUE)
		{
            Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
            return DCM_E_PENDING;
        }
		Index0 = Dcm_PageBufferData.IloopOne;
		ReqOffset = Dcm_PageBufferData.ReqOffset;
		ResOffset = Offset;
		Dcm_PageBufferData.PageTxOK = FALSE;
		Dcm_PageBufferData.LastFilled = TRUE;
	}
#endif

	if (OpStatus != DCM_PENDING)
	{
        ret = Dcm_Uds0x22ServiceConditonCheck(ProtocolCtrlId);
        if(E_OK != ret)
        {
            return ret;
        }
	}

	for (; (Index0 < DidNum)
#if (TRUE == DCM_PAGEDBUFFER_ENABLED)
    && ((Dcm_PageBufferData.LastFilled == TRUE) || (Dcm_PageBufferData.TotalSize == 0UL))
#endif
	; Index0++)
	{
		RecDid = (uint16)(((uint16)Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[ReqOffset]) << 8u) \
			    |((uint16)(Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[ReqOffset + 1u]));

		ReqOffset = ReqOffset + 2u;
		CheckOK = TRUE;
        /*************************************/
		if (Dcm_DspCfg.DcmDspEnableObdMirror == TRUE)
        {
            if ((RecDid >= 0xF400u) && (RecDid <= 0xF4FFu))/*[SWS_Dcm_00481]*/
            {
                /* Service $01 */
                switch(RecDid)
                {
                case 0xF400u:
                case 0xF420u:
                case 0xF440u:
                case 0xF460u:
                case 0xF480u:
                case 0xF4A0u:
                case 0xF4C0u:
                case 0xF4E0u:
                    if (MixPid == NORMAL_REQUEST)/*[SWS_Dcm_00943] */
                    {
                        (void)DslInternal_ResetResource(ProtocolCtrlId);
                        return E_NOT_OK;
                    }
                    /*[SWS_Dcm_00407]*/
                    if (E_OK != DspInternalUDS0x22_CheckSupported(RecDid, &ResOffset))
                    {
                        noFindPidNum++;
                    }
#if (TRUE == DCM_PAGEDBUFFER_ENABLED)
                    if ((ResOffset - Offset)
                        > (Dcm_DslCfg.pDcmChannelCfg[TxChannelCfgIndex].Dcm_DslBufferSize))
                    {
                    	Dcm_PageBufferData.LastFilled = FALSE;
                    }
#endif
                    MixPid = SUPPORT_REQUEST;
                    break;
                default:
                    if (MixPid == SUPPORT_REQUEST)/*[SWS_Dcm_00943] */
                    {
                        (void)DslInternal_ResetResource(ProtocolCtrlId);
                        return E_NOT_OK;
                    }
                    MixPid = NORMAL_REQUEST;
                    break;
                }
            }
            else if ((RecDid >= 0xF800u) && (RecDid <= 0xF8FFu))
            {
                /* Service $09 */
                switch(RecDid)
                {
                case 0xF800u:
                case 0xF820u:
                case 0xF840u:
                case 0xF860u:
                case 0xF880u:
                case 0xF8A0u:
                case 0xF8C0u:
                case 0xF8E0u:
                    if (MixPid == NORMAL_REQUEST)/*[SWS_Dcm_00943] */
                    {
                        (void)DslInternal_ResetResource(ProtocolCtrlId);
                        return E_NOT_OK;
                    }
                    /*[SWS_Dcm_00407]*/
                    if (E_OK != DspInternalUDS0x22_CheckSupported(RecDid, &ResOffset))
                    {
                        noFindPidNum++;
                    }
#if (TRUE == DCM_PAGEDBUFFER_ENABLED)
                    if ((ResOffset - Offset)
                        > (Dcm_DslCfg.pDcmChannelCfg[TxChannelCfgIndex].Dcm_DslBufferSize))
                    {
                    	Dcm_PageBufferData.LastFilled = FALSE;
                    }
#endif
                    MixPid = SUPPORT_REQUEST;
                    break;
                default:
                    if (MixPid == SUPPORT_REQUEST)/*[SWS_Dcm_00943] */
                    {
                        (void)DslInternal_ResetResource(ProtocolCtrlId);
                        return E_NOT_OK;
                    }
                    MixPid = NORMAL_REQUEST;
                    break;
		        }
            }
            else
            {}
        }
        if ((RecDid >= 0xF600u) && (RecDid <= 0xF6FFu))/*[SWS_Dcm_00482]*/
        {
            /* Service $06 */
            switch(RecDid)
            {
            case 0xF600u:
            case 0xF620u:
            case 0xF640u:
            case 0xF660u:
            case 0xF680u:
            case 0xF6A0u:
            case 0xF6C0u:
            case 0xF6E0u:
                if (MixPid == NORMAL_REQUEST)/*[SWS_Dcm_00943] */
                {
                    (void)DslInternal_ResetResource(ProtocolCtrlId);
                    return E_NOT_OK;
                }
                /*[SWS_Dcm_00407]*/
                if (E_OK != DspInternalUDS0x22_CheckSupported(RecDid, &ResOffset))
                {
                    noFindPidNum++;
                }
#if (TRUE == DCM_PAGEDBUFFER_ENABLED)
				if ((ResOffset - Offset)
				    > (Dcm_DslCfg.pDcmChannelCfg[TxChannelCfgIndex].Dcm_DslBufferSize))
				{
					Dcm_PageBufferData.LastFilled = FALSE;
				}
#endif
                MixPid = SUPPORT_REQUEST;
                break;
            default:
                if (MixPid == SUPPORT_REQUEST)/*[SWS_Dcm_00943] */
                {
                    (void)DslInternal_ResetResource(ProtocolCtrlId);
                    return E_NOT_OK;
                }
                MixPid = NORMAL_REQUEST;
                break;
            }
        }

        if (MixPid != SUPPORT_REQUEST)/*[SWS_Dcm_01195][SWS_Dcm_01197]*/
        {
            /*find the required DID in configuration*/
            ret = DspInternalUDS0x22_DidCheck(
                    OpStatus,
                    RecDid,
                    &RangeDidCfgIndex,
                    &DidCfgIndex,
                    &RangeDidFlag);
            if (E_NOT_OK == ret)
            {
            	NoFindDidNum++;
            	CheckOK = FALSE;
            }

            if (CheckOK == TRUE)
            {
            /**************************************/
            if (TRUE == RangeDidFlag)
            {
                DidInfoCfgIndex = Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].
                        DcmDspDidRangeInfoIndex;
            }
            else
            {
                DidInfoCfgIndex = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
                        DcmDspDidInfoIndex;
            }
            /*if the required DID is found,check whether the pDcmDspDidRead container is configured*/
             ret = DspInternalUDS0x22_DidInfoCheck(DidInfoCfgIndex);
            if(E_NOT_OK == ret)
            {
					NoFindDidReadNum++;
	            	CheckOK = FALSE;
            }

            /**************************************/
				if (CheckOK == TRUE)
            {
				/*SWS_Dcm_00433,SWS_Dcm_00434,SWS_Dcm_00435*/
				/*check the current session*/
				#if(STD_ON == DCM_SESSION_FUNC_ENABLED)
				ret = DspInternalUDS0x22_DidSessionCheck(
				        DidInfoCfgIndex,
				        &DidInfoSupportNum,
				        &DidSessionSupportNum);
				if(E_NOT_OK == ret)
				{
				    DidSessionCheck = FALSE;
				}
				#endif

				/***************************************/
				/*check the current security level*/
				#if(STD_ON == DCM_SECURITY_FUNC_ENABLED)
				ret = DspInternalUDS0x22_DidSecurityCheck(
				        DidInfoCfgIndex,
				        ErrorCode);
				if(E_NOT_OK == ret)
				{
					(void)DsdInternal_SetNrc(ProtocolCtrlId,*ErrorCode);
					DsdInternal_ProcessingDone(ProtocolCtrlId);
					return  E_NOT_OK;
				}
				#endif
            }

				if ((DidSessionCheck == TRUE) && (CheckOK == TRUE))
            {
                /***************************************/
                /*set the response message*/
                /**Dcm437**/
                Dcm_Channel[ResOffset] = (uint8)((RecDid) >> 8u);
                /*echo of DID MSB*/
                ResOffset = ResOffset + 1u;
                Dcm_Channel[ResOffset] = (uint8)(RecDid);
                ResOffset = ResOffset + 1u;

                if (FALSE == RangeDidFlag)
                {
                    /*SWS_Dcm_00578*/
                    ReadDidSignalFlag = Dsp_UDS0x22_DidEcuSignalCheck(
                            DidCfgIndex,
                            &ResOffset);
                    if (FALSE == ReadDidSignalFlag)
                    {
                        /***************************************/
                        /*check the current DID condition is OK*/
                        /*SWS_Dcm_00439*/
                        ret = DspInternalUDS0x22_DidConditionCheck(
                                OpStatus,
                                DidCfgIndex,
                                ErrorCode);
                        if(E_NOT_OK == ret)
                        {
                            (void)DsdInternal_SetNrc(ProtocolCtrlId,*ErrorCode);
                            DsdInternal_ProcessingDone(ProtocolCtrlId);
                            return E_NOT_OK;
                        }
                        else if (DCM_E_PENDING == ret)
                        {
                            Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
                            return ret;
                        }
                        else
                        {}

    #if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
                       Find = FALSE;
                       if ((Dcm_DspCfg.pDcmDspDidInfo[Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
                                 DcmDspDidInfoIndex].DcmDspDidDynamicallyDefined == TRUE)
                              && (Dcm_DspCfg.pDcmDspDidInfo[Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
                                  DcmDspDidInfoIndex].DcmDspDDDIDMaxElements > 0u)
                              && (RecDid > 0xF200u) && (RecDid < 0xF3FFu))
                       {
                           for (iloop = 0;
                                (iloop < DCM_DSP_DDDID_MAX_NUMBER) && (Find == FALSE);
                                iloop++)
                           {
                               if (RecDid == Dcm_DDDid[iloop].DDDid)
                               {
                                   Find = TRUE;
                               }
                           }

                           if(Find == TRUE)
                           {
                               ret = DspInternalUDS0x22_DDDIDcheckPerSourceDID(
                                       iloop,
                                       ErrorCode);

                               if (E_OK != ret)
                               {
                                   (void)DsdInternal_SetNrc(ProtocolCtrlId,*ErrorCode);
                                   DsdInternal_ProcessingDone(ProtocolCtrlId);
                                   return ret;
                               }
                               /*set the response message*/
                               /**Dcm437**/
                              ret = Dcm_UdsAssembleResponse_0x2C(   OpStatus,
                                                                  MsgCtrlId,
                                                               iloop,
                                                               ProtocolCtrlId,
                                                               &ResOffset,
                                                               ErrorCode);
                              if(E_NOT_OK == ret)
                              {
                                  return E_NOT_OK;
                              }
                              else if (DCM_E_PENDING == ret)
                              {
                                  Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
                                  return ret;
                              }
                              else
                              {}
                           }
                           else
                           {
                               /*[SWS_Dcm_00651]*/
                               (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
                               DsdInternal_ProcessingDone(ProtocolCtrlId);
                               return E_NOT_OK;
                           }
                       }
                       else
    #endif
                       {
                            /*set the response message*/
                            /**Dcm437**/
                           ret = Dcm_UdsAssembleResponse(   OpStatus,
                                                            ProtocolCtrlId,
                                                            DidCfgIndex,
                                                            &ResOffset,
                                                            ErrorCode);
                           if(E_NOT_OK == ret)
                           {
                               return E_NOT_OK;
                           }
                           else if (DCM_E_PENDING == ret)
                           {
                               Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
                               return ret;
                           }
                           else
                           {}
                       }
    #if (TRUE == DCM_PAGEDBUFFER_ENABLED)
                        if ((ResOffset - Offset)
                            > (Dcm_DslCfg.pDcmChannelCfg[TxChannelCfgIndex].Dcm_DslBufferSize))
                        {
                            Dcm_PageBufferData.LastFilled = FALSE;
                        }
    #endif
                    }
                }
                else
                {
                    /***************************************/
                     /*Read the current length of the data in DID*/
                     ret = DspInternalUDS0x22_ReadRangeDidDataLength(
                             OpStatus,
                             RecDid,
                             RangeDidCfgIndex,
                             &DidSize,
                             ErrorCode);

                    if(E_NOT_OK == ret)
                    {
                       (void)DsdInternal_SetNrc(ProtocolCtrlId,*ErrorCode);
                       DsdInternal_ProcessingDone(ProtocolCtrlId);
                       return  E_NOT_OK;
                    }
                    else if (DCM_E_PENDING == ret)
                    {
                        Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
                        return ret;
                    }
                    else
                    {
                        /*DidSize over the DcmDspDidRangeMaxDataLength,Send NRC 0x22*/
                        if (DidSize > Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].DcmDspDidRangeMaxDataLength)
                        {
                            (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_CONDITIONSNOTCORRECT);
                            DsdInternal_ProcessingDone(ProtocolCtrlId);
                            return  E_NOT_OK;
                         }
                    }

                    /*set the response message*/
                    /**Dcm437**/
                     ret = Dcm_UdsAssembleRangeDidResponse(
                              OpStatus,
                              ProtocolCtrlId,
                              RangeDidCfgIndex,
                              &ResOffset,
                              RecDid,
                              DidSize,
                              ErrorCode);
                     if(E_NOT_OK == ret)
                     {
                         return E_NOT_OK;
                     }
                     else if (DCM_E_PENDING == ret)
                     {
                         Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
                         return ret;
                     }
                     else
                     {}
    #if (TRUE == DCM_PAGEDBUFFER_ENABLED)
                    if ((ResOffset - Offset)
                        > (Dcm_DslCfg.pDcmChannelCfg[TxChannelCfgIndex].Dcm_DslBufferSize))
                    {
                        Dcm_PageBufferData.LastFilled = FALSE;
                    }
    #endif
                }
	#if (TRUE == DCM_PAGEDBUFFER_ENABLED)
            Dcm_PageBufferData.LastFilledSize = DidSize;
	#endif
            }
            }
        }
	}

	if ((NoFindDidNum == DidNum) || (NoFindDidReadNum == DidNum) || (DidSessionSupportNum == 0u))
	{
		/*Dcm438:if the required DID is not found in DcmDspDid,send NRC 0x31*/
	    /*at least one DID is supported in the active session,not then send NRC 0x31*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return  E_NOT_OK;
	}

    /* can not find supported DIDs,ignose the requested message */
    if (noFindPidNum == DidNum)
    {
        /* there is no supported PID,ignore the request message */
        (void)DslInternal_ResetResource(ProtocolCtrlId);
        return E_NOT_OK;
    }

    /* check tx data length */
    if
#if(STD_ON == DCM_PAGEDBUFFER_ENABLED)
          (
#endif
    ((ResOffset - Offset) > (Dcm_DslCfg.pDcmChannelCfg[TxChannelCfgIndex].Dcm_DslBufferSize))
#if(STD_ON == DCM_PAGEDBUFFER_ENABLED)
        || (0UL != Dcm_PageBufferData.TotalSize))
    {
        if(0UL == Dcm_PageBufferData.TotalSize)
        {
            Dcm_PageBufferData.TotalSize = (uint32)ResOffset - Offset;
            DsdInternal_StartPagedProcessing(ProtocolCtrlId);
        }
        else
        {
            if (Dcm_PageBufferData.LastFilled == TRUE)
            {
                Dcm_PageBufferData.IloopOne = Index0;
                Dcm_PageBufferData.ReqOffset = ReqOffset;
                Dcm_PageBufferData.ThisPageSize = ResOffset - Offset;
            }
            else
            {
                Dcm_PageBufferData.IloopOne = Index0 - 1u;
                Dcm_PageBufferData.ReqOffset = ReqOffset - 2u;
                Dcm_PageBufferData.ThisPageSize =
                    ResOffset - Offset - Dcm_PageBufferData.LastFilledSize;
            }
            Dcm_PageBufferData.PageIndex += 1u;
            Dcm_PageBufferData.Filled = TRUE;

            DsdInternal_ProcessPage(ProtocolCtrlId);
            if (Dcm_PageBufferData.TimeOut == TRUE)
            {
                return E_NOT_OK;
            }
            Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
            return DCM_E_PENDING;
        }
        if (Dcm_PageBufferData.TotalSize
            > Dcm_DslCfg.pDcmDslProtocol->pDcmDslProtocolRow[ProtocolCtrlId].
            DcmDslProtocolMaximumResponseSize)
        {
            /*Pdu length is bigger than Page buffer max size */
            (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_RESPONSETOOLONG);
            DsdInternal_ProcessingDone(ProtocolCtrlId);
            DslInternal_InitPageBuffer();
            return E_NOT_OK;
        }
        Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
        return DCM_E_PENDING;
    }
#else
		{
			/*Pdu length is bigger than buffer size */
			(void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_RESPONSETOOLONG);
			DsdInternal_ProcessingDone(ProtocolCtrlId);
			return E_NOT_OK;
		}
#endif
	SchM_Enter_Dcm(Dcm_MsgCtrl);
	Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResMaxDataLen = (Dcm_MsgLenType)ResOffset - Offset;
	Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResDataLen    = (Dcm_MsgLenType)ResOffset - Offset;
	Dcm_MsgCtrl[MsgCtrlId].MsgContext.pResData      = &Dcm_Channel[Offset];
	SchM_Exit_Dcm(Dcm_MsgCtrl);
	DsdInternal_ProcessingDone(ProtocolCtrlId);
	return  E_OK;
#endif
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif
